<template>
  <div class="questionsAnswers" @click="menuVisible = false">
    <div class="questions" :style="{ width: panelWidth.l }">
      <div class="windowTitle">{{ menuBar }}</div>
      <div class="top" ref="queAnsTop">
        <div class="scollBox" ref="queAnsScollBox">
          <div v-for="(item, index) in content" :key="index">
            <div class="messageInfo" :class="{ messageInfoRight: item.sender == 'user' }">
              <img v-if="item.sender == 'assistant'" src="@/assets/image/waterMap/robot.png" alt="" />
              <img v-else src="@/assets/image/waterMap/user.png" alt="" />
              <div v-if="item.text" class="text">
                <div v-html="item.text"></div>
                <el-rate
                  v-if="rateVisibleFun(item, index)"
                  v-model="item.rateValue"
                  @change="handleRate(item)"
                  show-text
                  :colors="['#99A9BF', '#F7BA2A', '#f1ab42']">
                </el-rate>
              </div>
              <div v-else v-loading="loadingObj[index]" element-loading-spinner="el-icon-loading" class="askLoading"></div>
            </div>
            <template v-if="item?.fileList?.length">
              <div class="fileRelated" v-for="(ele, i) in item.fileList" :key="index + ele.file_name + i">
                <fileCard :info="ele" @priview="priviewFile"></fileCard>
                <i v-if="ele.content" @click="relatedContents(item, ele)" class="iconfont icon-zhushi" title="文件相关内容"></i>
              </div>
            </template>
          </div>
        </div>
      </div>
      <div class="bottom">
        <el-input
          type="textarea"
          placeholder="请输入内容"
          v-model="textarea"
          @keydown.enter.native="noLineBreaks"
          @keyup.enter.native="sendMessage"></el-input>
        <div class="lastRow">
          <div class="left">
            <img @click.stop="menuVisible = true" src="@/assets/image/window/menu.png" alt="" />
            <img @click="visibleHistory" src="@/assets/image/window/history.png" alt="" />
          </div>
          <div class="right">
            <img src="@/assets/image/window/voice.png" alt="" />
            <el-button @click="sendMessage" class="button-gradient" size="medium">发送</el-button>
            <i @click="newAction" title="新建会话" class="el-icon-circle-plus-outline"></i>
          </div>
        </div>
      </div>
    </div>
    <!-- 右侧面板 -->
    <div v-if="rightPanleVisible" class="filePreview" :style="{ width: panelWidth.r }">
      <div class="fileInfo">
        <div class="title">
          <div>{{ rightTitle }}</div>
          <div class="el-icon-close" @click="rightPanleVisible = false"></div>
        </div>

        <component v-if="rightTitle == '详情'" :is="fileType" :info="fileInfo"></component>
        <dialogueHistory @resetContent="resetContent" v-if="rightTitle == '对话记录'"></dialogueHistory>
        <selectionKnowledge v-if="rightTitle == '选择文件库'"></selectionKnowledge>
      </div>
    </div>
    <!--文件相关片段  -->
    <parentDialog title="文件相关片段" :visible.sync="dialogVisible" v-if="dialogVisible">
      <p class="relatedFragment">{{ relatedFragment }}</p>
    </parentDialog>
    <!-- 菜单栏 -->
    <div class="menuBox" @click.stop="() => {}" v-if="menuVisible">
      <el-cascader-panel :options="cascaderOptions" @change="cascaderblur"></el-cascader-panel>
      <!-- <el-cascader-panel :props="{ multiple: true }" :options="cascaderOptions" @change="cascaderblur"></el-cascader-panel> -->
    </div>
  </div>
</template>

<script>
import { knowledgeChatMultibase, QAmain, markZhishui } from "@/api/chartWindow";
import { knowledgeListBases } from "@/api/KnowledgeBaseManagement";
import fileCard from "@/components/intelligentAssistant/fileCard.vue"; // 文件显示
import txt from "@/components/priviewFile/txt.vue";
import pdf from "@/components/priviewFile/pdf.vue";
import docx from "@/components/priviewFile/docx.vue";
import xlsx from "@/components/priviewFile/xlsx.vue";
import parentDialog from "@/components/dialog/parentDialog.vue"; // 文件相关片段
import dialogueHistory from "@/components/intelligentAssistant/dialogueHistory.vue"; // 对话记录
import selectionKnowledge from "@/components/intelligentAssistant/selectionKnowledge.vue";

import MarkdownIt from "markdown-it";

export default {
  components: { fileCard, parentDialog, txt, pdf, docx, xlsx, dialogueHistory, selectionKnowledge },
  data() {
    // html：是否允许在Markdown文本中使用HTML标签，默认值为false。
    // breaks：是否将连续的换行符转换为<br>标签，默认值为false。
    // typographer：是否启用智能引号和破折号等Typographer功能，默认值为false。
    // linkify：是否将URL转换为链接，默认值为false。
    // highlight：代码高亮函数。
    let md = new MarkdownIt()
      .set({ html: true, breaks: true, typographer: true, linkify: true })
      .set({ highlight: (code, lang) => highlight(code, lang) });
    return {
      rightPanleVisible: false,
      content: [
        {
          sender: "assistant",
          text: "这里是水利部知识平台智能助手，有问题可以随时问我哦～",
        },
      ],
      cascaderOptions: [
        {
          value: "ssfw",
          label: "搜索范围",
        },
        // {
        //   value: "newAction",
        //   label: "新建会话",
        // },
      ],
      menuVisible: false,
      textarea: "", // 输入框
      fileInfo: {}, // 文件详情
      loading: false, // 问答loading
      dialogVisible: false, // 文件相关片段控制
      relatedFragment: "", // 文件相关片段内容
      rightTitle: "详情", // 右侧面板标题
      fileType: "", // 文件类型
      sessionId: null,
      loadingObj: {},
      md: md,
      historyList: [],
      iconClasses: ["iconfont icon-icon-rate-face-", "iconfont icon-icon-rate-face-1", "iconfont icon-icon-rate-face-2"], // 等同于 { 2: 'icon-rate-face-1', 4: { value: 'icon-rate-face-2', excluded: true }, 5: 'icon-rate-face-3' }
      // selectionknowledge: ["公共文档库", "test"],
    };
  },
  computed: {
    panelWidth() {
      let width = 0;
      if (this.rightPanleVisible) {
        if (this.rightTitle == "选择文件库") width = 20;
        else if (this.rightTitle == "对话记录") width = 35;
        else width = 40;
      }
      return { l: 100 - width + "%", r: width + "%" };
    },
    selectionknowledgeV() {
      let arr = this.$store.state.selectionKnowledge;
      if (arr.length) {
        return [...arr.map(v => v.id).filter(v => v != "个人知识库")];
      } else {
        return [1];
      }
    },
    menuBar() {
      let name = "全局问答";
      let arr = this.$store.state.selectionKnowledge;
      let list = [...arr.map(v => v.label)];
      if (list.includes("公共文档库") && list.length > 1) name = "全局+个人";
      else if (list.includes("公共文档库")) name = "全局问答";
      else if (list.includes(`dev-cx-temp-${localStorage.getItem("userName")}`)) name = "临时问答";
      else name = "个人问答";
      return name;
    },
  },
  mounted() {
    // this.getknowledgeList();
  },
  methods: {
    // 回答评分
    handleRate(item) {
      let { sessionId, gmtModified, rateValue: mark } = item;
      markZhishui({ sessionId, gmtModified, mark })
        .then(result => {
          if (result.code == 200) this.$message.success(result.msg);
          else this.$message.error(result.msg);
        })
        .catch(err => {
          console.log(err);
        });
    },
    newAction() {
      this.sessionId = null;
      this.content = [
        {
          sender: "assistant",
          text: "这里是水利部知识平台智能助手，有问题可以随时问我哦～",
        },
      ];
    },
    cascaderblur(item) {
      if (item[0] == "ssfw") {
        this.rightPanleVisible = true;
        this.rightTitle = "选择文件库";
      } else if (item[0] == "newAction") {
        this.sessionId = null;
        this.content = [
          {
            sender: "assistant",
            text: "这里是水利部知识平台智能助手，有问题可以随时问我哦～",
          },
        ];
      }
      this.menuVisible = false;
    },
    // 文件相关内容弹窗
    relatedContents(item, fileContent) {
      this.relatedFragment = fileContent.content;
      this.dialogVisible = true;
    },
    // 发送消息
    sendMessage() {
      let input = this.textarea.replace(/\r|\n/gi, "");
      if (!input) return;
      this.textarea = "";
      this.historyList.push({
        role: "user",
        content: input,
      });
      this.content.push({
        sender: "user",
        text: input,
      });
      this.content.push({
        sender: "assistant",
      });
      this.loading = true;
      this.getScollHeight();
      let index = this.content.length - 1;
      this.loadingObj[index] = true;
      QAmain({
        sessionId: this.sessionId,
        query: input,
        kbIds: this.selectionknowledgeV,
        history: this.historyList.slice(-10),
      })
        .then(result => {
          this.loadingObj[index] = false;
          this.sessionId = this.sessionId || result?.data?.sessionId;

          this.historyList.push({
            role: "assistant",
            content: result?.data?.answer || "",
          });
          let obj = {
            sender: "assistant",
            text: this.handleMackdown(result?.data?.answer || ""),
            fileList: [],
          };

          if (result.code == 200 && result?.data?.answer != "连接超时！") {
            obj.rateValue = 0;
            obj.sessionId = this.sessionId;
            obj.gmtModified = result?.data?.gmtCreated;
            if (result?.data?.docs && !result?.data?.docs.includes("未找到相关文档")) {
              //判断是否有关联文件
              let docs = JSON.parse(result?.data?.docs);
              let fileList = [];
              docs.forEach(item => {
                let obj = fileList.find(v => v.file_name == item.file_name);
                if (!obj) fileList.push(item);
              });
              obj.fileList = fileList;
            } else {
              obj.fileList = [];
            }
          } else {
            obj.text = "暂时无法查询，请稍后再试！";
          }
          this.$set(this.content, index, obj);
          delete this.loadingObj[index];
          this.getScollHeight();
        })
        .catch(err => {
          this.content[index].text = "请求超时，请稍后再试！";
          this.loadingObj[index] = false;
          delete this.loadingObj[index];
          // this.loading = false;
          console.log(err);
        });
    },
    // 对话记录
    visibleHistory() {
      this.rightTitle = "对话记录";
      this.rightPanleVisible = true;
    },
    // 文件预览
    priviewFile(info) {
      this.rightTitle = "详情";
      this.rightPanleVisible = true;
      this.fileInfo = info;
      this.fileType = info.file_url.split(".").at(-1);
    },
    // 获取滚条位置
    getScollHeight() {
      this.$nextTick(() => {
        this.$refs.queAnsTop.scrollTop = this.$refs.queAnsScollBox?.offsetHeight;
      });
    },
    // 禁止回车换行
    noLineBreaks(e) {
      var et = e || window.event;
      var keycode = et.charCode || et.keyCode;
      if (keycode == 13) {
        if (window.event) {
          window.event.returnValue = false;
        } else {
          e.preventDefault(); //for firefox
        }
      }
    },
    // 历史记录更新
    resetContent(item, sessionId) {
      this.sessionId = sessionId;
      this.history = item.map(v => {
        return {
          role: item.sender,
          content: v.text,
        };
      });
      this.content = item.map(v => {
        return {
          ...v,
          text: this.handleMackdown(v.text),
        };
      });
      console.log(this.content);
      this.getScollHeight();
    },
    // 获取文件库列表
    async getknowledgeList() {
      let res = await knowledgeListBases({
        size: 1000,
        page: 1,
      });
      if (res.code == 200) {
        this.knowledgeBase.myKnowledge = res.data.records.map(v => v.libName);
      }
    },
    handleMackdown(markdownText) {
      let html = markdownText
        .replace(/`/gi, "")
        .split("\n")
        .reduce((prev, cur, index, arr) => {
          return this.md.render(prev) + (this.md.render(cur) || cur);
        }, "");
      return html;
    },
    rateVisibleFun(item, index) {
      return item.sender == "assistant" && index != 0 && (item.rateValue || item.rateValue == 0) && !item.text.includes("连接超时");
    },
  },
};
</script>
<style lang="scss" scoped>
.questionsAnswers {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
  .questions {
    width: calc(60% - 20px);
    // margin-right: 20px;
    height: 100%;
    border-radius: 10px;
    background: rgba(243, 244, 246, 1);
    .windowTitle {
      font-size: 18px;
      font-weight: bold;
      color: #606266;
      text-align: left;
      margin: 15px;
      // margin-left: 20px;
    }
    .top {
      height: calc(70% - 30px);
      border-bottom: 1px solid rgba(0, 20, 45, 0.15);
      padding: 20px 10px;
      box-sizing: border-box;
      overflow: auto;
      padding-top: 0px;
      .scollBox {
        > :nth-child(1) {
          .messageInfo {
            margin-top: 0px;
          }
        }
      }
      .messageInfo {
        margin-top: 15px;
        display: flex;
        align-items: flex-start;
        > img {
          width: 52px;
          height: 52px;
          margin-right: 10px;
          border-radius: 50%;
        }
        .text {
          font-size: 16px;
          padding: 8px 15px;
          text-align: left;
          line-height: 35px;
          // white-space: pre-line;
          border-radius: 20px 20px 20px 0px;
          background: rgba(30, 104, 231, 0.17);
          max-width: 80%;
          .el-rate {
            text-align: right;
          }
        }
        .askLoading {
          margin-top: 40px;
        }
      }
      .messageInfoRight {
        flex-direction: row-reverse;
        > img {
          margin-left: 5px;
        }
        .text {
          border-radius: 20px 20px 0px 20px;
          text-align: left;
          max-width: 77%;
        }

        .askLoading {
          margin-right: 20px;
        }
      }
      .fileRelated {
        display: flex;
        align-items: center;
        text-align: left;
        > i {
          color: #c0c0c0;
          display: block;
          margin-left: 5px;
          cursor: pointer;
        }
      }
    }
    .bottom {
      height: calc(30% - 34px);
      position: relative;
      padding: 10px;
      box-sizing: border-box;
      ::v-deep .el-textarea {
        height: calc(100% - 40px);
        .el-textarea__inner {
          height: 100%;
          border: none;
          font-size: 18px;
          color: #000;
          background: rgba(243, 244, 246, 1);
        }
      }
      .lastRow {
        display: flex;
        justify-items: flex-end;
        align-items: center;
        width: calc(100% - 20px);
        position: absolute;
        bottom: 5px;
        justify-content: space-between;
        .left {
          img {
            width: 22px;
            height: 22px;
            margin: 0px 10px;
            cursor: pointer;
          }
        }
        .right {
          display: flex;
          align-items: center;
          img {
            margin: 0px 10px;
          }

          i {
            font-size: 18px;
            font-weight: bold;
            color: #909399;
            margin-left: 5px;
            cursor: pointer;
          }
        }
      }
    }
  }
  .filePreview {
    width: calc(40%);
    height: 100%;
    margin-left: 15px;
    padding-bottom: 10px;
    border-radius: 10px;
    background: #fff;
    box-sizing: border-box;
    text-align: left;
    .fileInfo {
      padding: 0px 10px 10px;
      height: calc(100% - 10px);
      overflow: hidden;
    }
    .title {
      font-size: 16px;
      font-weight: 600;
      color: #00142d;
      line-height: 40px;
      background: rgba(131, 150, 181, 0.05);
      display: flex;
      align-items: center;
      justify-content: space-between;
      width: calc(100% + 20px);
      margin-left: -10px;
      padding: 2px 15px 2px 15px;
      box-sizing: border-box;
      :nth-child(2) {
        font-weight: bold;
        font-size: 18px;
        color: #666;
        cursor: pointer;
      }
    }
    .imports {
      margin: 20px 0px;
    }

    .title2 {
      font-size: 14px;
      font-weight: 600;
      color: #00142d;
      line-height: 19px;
      margin-bottom: 10px;
    }

    .text-con {
      padding: 10px;
      background: rgba(131, 150, 181, 0.1);
    }
    h2 {
      text-align: center;
      font-size: 18px;
      font-family: MiSans, MiSans;
      font-weight: 600;
      color: #00142d;
      line-height: 40px;
    }
    p {
      font-size: 16px;
      text-indent: 2em;
      line-height: 30px;
    }
  }
  .relatedFragment {
    text-align: left;
    font-size: 16px;
    height: 100%;
    width: 100%;
    white-space: pre-line;
    overflow: auto;
  }
  .menuBox {
    position: absolute;
    bottom: 70px;
    left: 335px;
    .el-cascader-panel {
      text-align: left;
      background: #fff;
    }
    ::v-deep .el-cascader-menu__wrap {
      height: auto;
    }
  }
}
</style>
